package com.aofeng.hybrid.android;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.webkit.WebView;
import android.widget.Toast;

import com.aofeng.hybrid.R;
import com.aofeng.hybrid.activity.HybridActivity;
import com.aofeng.hybrid.plugin.H5Param;
import com.aofeng.hybrid.plugin.NativeCallJS;
import com.aofeng.hybrid.plugin.TaskExecutor;
import com.aofeng.hybrid.service.GenericService;
import com.aofeng.hybrid.util.LogUtil;

import org.json.JSONObject;

import java.io.File;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;

/**
 * 本地被调用方法基础类
 * @author LGY
 *
 */
public class NativeBaseMethod {

    private static Map<String, Object> services = new HashMap<String, Object>();

    /**
     * 打开h5页面或者是本地页面g
     * @param webView 浏览器
     * @param jo 页json对象
     * */
    @SuppressLint("DefaultLocale")
	public static void _open_a_page (WebView webView, JSONObject jo) throws Exception {
    	try {
        	Context context = webView.getContext();
	        if(jo.getString("type").toLowerCase().equals("native")) {
	    		startupNativePage(jo.getString("page"), jo.getString("param"), context);
	        } else {
	    		startupH5Page(jo.getString("page"), jo.getString("method"), context);
	        }
    	} catch(Exception e) {
    		LogUtil.d("NativeBaseMethod", "打开新页面出错。");
            throw e;
    	}
    }

    /**
     ** 执行异步业务
     */
	public static void _executeAsyncTask(final WebView webView, final JSONObject jo, final NativeCallJS jsCallback) throws Exception {
        try {
            String className = jo.getString("type");
            final Object service;
            if(!services.containsKey(className)) {
                String mangledName = "com.aofeng.hybrid.service." + className.substring(0, 1).toUpperCase() + className.substring(1) + "Service";
                Class<?> clazz = Class.forName(mangledName);
                Constructor<?> ctor = clazz.getConstructor(Context.class);
                //give application context to avoid sticky activity
                service = ctor.newInstance(new Object[]{webView.getContext().getApplicationContext()});
                services.put(className, service);
            } else {
                service = services.get(className);
            }
            TaskExecutor.scheduleTaskOnUiThread(0, new Runnable() {
                @Override
                public void run() {
                    try {
                        jsCallback.apply(((GenericService)service).action(jo.getJSONObject("data")));
                    } catch (Exception e) {
                        LogUtil.d("NativeBaseMethod", "调用服务出错。");
                    }
                }
            });
        } catch (Exception e) {
            LogUtil.d("NativeBaseMethod", "调用服务出错。");
            throw e;
        }
	}

    /**
     ** 执行异步业务
     */
    public static JSONObject _executeTask(final WebView webView, final JSONObject jo) throws Exception{
        try {
            String className = jo.getString("type");
            final Object service;
            if(!services.containsKey(className)) {
                String mangledName = "com.aofeng.hybrid.service." + className.substring(0, 1).toUpperCase() + className.substring(1) + "Service";
                Class<?> clazz = Class.forName(mangledName);
                Constructor<?> ctor = clazz.getConstructor(Context.class);
                //give application context to avoid sticky activity
                service = ctor.newInstance(new Object[]{webView.getContext().getApplicationContext()});
                services.put(className, service);
            } else {
                service = services.get(className);
            }
            return ((GenericService)service).action(jo.getJSONObject("data"));
        } catch (Exception e) {
            LogUtil.d("NativeBaseMethod", "调用服务出错。");
            throw e;
        }
    }

    /**
     * 系统弹出提示框
     * @param webView 浏览器
     * @param message 提示信息
     * */
    public static void alert (WebView webView, String message) {
        // 构建一个Builder来显示网页中的alert对话框
        AlertDialog.Builder builder = new AlertDialog.Builder(webView.getContext());
        builder.setTitle(webView.getContext().getString(R.string.dialog_title_system_msg));
        builder.setMessage(message);
        builder.setPositiveButton(android.R.string.ok, new AlertDialog.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        builder.setCancelable(false);
        builder.create();
        builder.show();
    }

    public static void alert (WebView webView, int msg) {
        alert(webView, String.valueOf(msg));
    }

    public static void alert (WebView webView, boolean msg) {
        alert(webView, String.valueOf(msg));
    }

    /**
     * 短暂气泡提醒
     * @param webView 浏览器
     * @param message 提示信息
     * */
    public static void toast (WebView webView, String message) {
        Toast.makeText(webView.getContext(), message, Toast.LENGTH_SHORT).show();
    }

    /**
     * 短暂气泡提醒
     * @param webView 浏览器
     * @param jo 提示信息
     * */
    public static void toast (WebView webView, JSONObject jo) {
        Toast.makeText(webView.getContext(), jo.toString(), Toast.LENGTH_SHORT).show();
    }
    /**
     * 可选择时间长短的气泡提醒
     * @param webView 浏览器
     * @param message 提示信息
     * @param isShowLong 提醒时间方式
     * */
    public static void toast (WebView webView, String message, int isShowLong) {
        Toast.makeText(webView.getContext(), message, isShowLong).show();
    }

    /**
     * 结束当前窗口
     * @param view 浏览器
     * */
    public static void goBack (WebView view) {
        if (view.getContext() instanceof Activity) {
            ((Activity)view.getContext()).finish();
        }
    }

    private static void startupNativePage(String page, String param, Context context)
			throws ClassNotFoundException {
        //page com.aofeng.hybrid.activity.xxxActivity
        LogUtil.d("NativeBaseMethod", page);
        Intent intent = new Intent(context, Class.forName(page));
		Bundle bundle = new Bundle();
		bundle.putString("param", param);
		intent.putExtras(bundle);
		context.startActivity(intent);
	}

	private static void startupH5Page(String page, String method, Context context) {
		Intent intent = new Intent(context, HybridActivity.class);
		Bundle bundle = new Bundle();
		if(!page.startsWith("http://"))
			page = "file://" + context.getFilesDir().getAbsolutePath()+ File.separator + "www/" + page;
        LogUtil.d("NativeBaseMethod", page);
        //method: com.aofeng.hybrid.android.Page1Method
		bundle.putSerializable("param", new H5Param(page, method));
		intent.putExtras(bundle);
		context.startActivity(intent);
	}

}